package gis.lifay.sdk;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.Assert;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.nio.charset.StandardCharsets;

/**
 *@ClassName TileSdk
 *@Description 切片SDK类
 *@Author lifay
 *@Date 2021/11/1 11:30
 **/
public class WrapSdk {

    private static Logger log = LoggerFactory.getLogger(WrapSdk.class);

    private static final String WRAP_SDK_DLL = System.getProperty("user.dir") + File.separator + "dll" + File.separator + "wrap.exe";

    public static class ExecBody {
        private int code;
        private String msg;
        private float time;

        public float getTime() {
            return time;
        }

        public void setTime(float time) {
            this.time = time;
        }

        public int getCode() {
            return code;
        }

        public void setCode(int code) {
            this.code = code;
        }

        public String getMsg() {
            return msg;
        }

        public void setMsg(String msg) {
            this.msg = msg;
        }
    }

    public static void checkSdk() {
        Assert.isTrue(FileUtil.exist(WRAP_SDK_DLL));
    }

    /**
     * 切片
     * @param inputFilePath
     * @param outFilePath
     * @return
     * @throws Exception
     */
    public static ExecBody process(String inputFilePath, String outFilePath) throws Exception {
        //检查sdk文件
        checkSdk();
        //检查输入参数
        Assert.notBlank(inputFilePath);
        Assert.notBlank(outFilePath);

        //检查文件
        if (!FileUtil.exist(inputFilePath)) {
            throw new FileNotFoundException("file not find :" + inputFilePath);
        }
        //组装参数
        String cmd = build(inputFilePath, outFilePath);
        //获取临时日志文件
        //String tempLogPath = getLogPath(tileModel.getId());
        //执行
        long s = System.currentTimeMillis();
        ExecBody execBody = exec(cmd);
        long e = System.currentTimeMillis();
        execBody.setTime((float) (e - s) / 1000);
        return execBody;
    }

    public static String getLogPath(String id) {
        return System.getProperty("user.dir") + File.separator + "logs" + File.separator + id + ".log";
    }

    /**
     * 组装参数
     * tile.exe --no-kml -p raster --zoom=0-6 -nb_processes=2 D:\IdeaProjects\TestHDFInstal\H4GRImage_bytesNature.jpg F:\\OutFile\\test_band-exe1-jpg
     * @return
     */
    private static String build(String inputFilePath, String outFilePath) {
        StringBuffer sb = new StringBuffer(WRAP_SDK_DLL);
        sb.append(" ");

        sb.append(inputFilePath).append("  ");

        sb.append(outFilePath);
        return sb.toString();
    }

    /**
     * 执行命令
     * @param cmd
     * @return
     */
    public static ExecBody exec(String cmd) {
        log.info("cmd >> " + cmd);
        ExecBody execBody = new ExecBody();
        StringBuilder stringBuilder = new StringBuilder();
        Process process = null;
        try {
            process = Runtime.getRuntime().exec(cmd);
            final InputStream is1 = process.getInputStream();
            new Thread(() -> {
                BufferedReader bufferedReader = null;
                String line = null;
                try {
                    bufferedReader = new BufferedReader(
                            new InputStreamReader(is1, "GBK"));
                    while ((line = bufferedReader.readLine()) != null) {
                        stringBuilder.append(line + "\n");
                    }
                    is1.close();
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }).start(); // 启动单独的线程来清空p.getInputStream()的缓冲区
            InputStream is2 = process.getErrorStream();
            BufferedReader br2 = new BufferedReader(new InputStreamReader(is2));
            StringBuilder buf = new StringBuilder(); // 保存输出结果流
            String line2 = null;
            while ((line2 = br2.readLine()) != null) buf.append(line2); //
            stringBuilder.append("&").append(buf);
        } catch (Exception e) {
            e.printStackTrace();
            execBody.setMsg(e.getMessage());
        } finally {
            //log.info(stringBuilder.toString());
        }
        execBody.setMsg(stringBuilder.toString());
        return execBody;
    }

    /**
     * 将输出内容写入本地日志文件
     * @param logPath
     * @param line
     */
    private static synchronized void logToLocal(String logPath, boolean error, String line) {
        FileUtil.writeString(line + "\n", new File(logPath), StandardCharsets.UTF_8);
        if (error) {
            log.error(line);
        } else {
            log.info(line);
        }
    }

    /**
     * 生成缩略图
     * @param src
     * @param dst
     * @param ext
     * @param w
     * @param h
     * @throws IOException
     */
    public static void toShrotImg(String src, String dst, String ext, int w, int h) throws IOException {
        BufferedImage bis = ImageIO.read(new File(src));
        BufferedImage bid = new BufferedImage(w, h, 1);
        Graphics2D g = bid.createGraphics();
        //将读取原文件 写在目标文件的 0,0  w h 范围
        g.drawImage(bis, 0, 0, w, h, null);
        FileOutputStream fileOutputStream = new FileOutputStream(dst);
        ImageIO.write(bid, ext, fileOutputStream);
        g.dispose();
        fileOutputStream.close();
    }

    public static void main(String[] args) throws Exception {
        process("D:\\IdeaProjects\\bootplus-master\\upload\\MonitorData\\GPP\\image\\GPP.png", "D:\\IdeaProjects\\bootplus-master\\upload\\MonitorData\\GPP\\image\\GPP2.tif");
    }
}
